import { Component, VNode } from "vue";
import Nifi from "./nifi";
import type { IPackAntvX6, Cell, Node, Edge } from "pack-antv-x6";

export namespace IPackNifi {
    export interface Props extends NifiConfig { }

    export type SC = string | Cell;

    export interface NifiConfig {
        id: string
        api?:{
            post: (url: string, data?: any, options?: any) => Promise<any>
            get: (url: string, options?: any) => Promise<any>
            put: (url: string, data?: any, options?: any) => Promise<any>
            delete: (url: string, options?: any) => Promise<any>
        }
    }


    export type NIFI_CELL_NAME =
        | "processors"
        | "process-groups"
        | "input-ports"
        | "output-ports"
        | "labels"
        | "funnels"
        | "connections"
        | "templates"
        | "remote-process-groups"

    export type NIFI_CAMEL_NAME =
        | "processors"
        | "processGroups"
        | "inputPorts"
        | "outputPorts"
        | "labels"
        | "funnels"
        | "connections"
        | "templates"
        | "remoteProcessGroups"

    export type NIFI_CELL_STATUS = "Invalid" | "Running" | "Stopped" | "Disabled" | "Validating" | "RUN"

    export interface NIFI_FLOW_GROUP {
        id: string
        flow: { connections: any[], funnels: any[], inputPorts: any[], labels: any[], outputPorts: any[], processGroups: any[], processors: any[], remoteProcessGroups: any[] }
        bulletins: any[]
        breadcrumb: NIFI_BREADCRUMB
    }

    export interface NIFI_BREADCRUMB {
        id: string
        name: string
        versionControlInformation: any
    }

    export interface NifiProps {
        nifi: Nifi
    }

    export interface CellProps {
        cell: Cell
        nifi: Nifi
        box?: IPackAntvX6.DrawerEl
        disabled?: boolean
    }

    export interface ModuleProps {
        nifi: Nifi
    }

    export interface CellApi {
        //
        get: (cell: Cell) => Promise<any>
        add: (cell: Cell | string, data: any) => Promise<any>
        update: (cell: Cell | string, data: any) => Promise<any>
        remove: (cell: Cell) => Promise<any>
        status: (cell: Cell, state: "RUN_ONCE" | "STOPPED" | "RUNNING" | "DISABLED" | "ENABLED") => Promise<any>
        //
        layout: (mds: any[]) => any[]
        refreshProp: (e: SC, data: any, options?: any) => void
        //
        edit: (e: NIFI_CAMEL_NAME | Cell, args?: any[]) => void
        view: (e: NIFI_CAMEL_NAME | Cell, args?: any[]) => void
        //
        blank: Partial<CellItemApi>
        processors: CellPorcessorsApi
        processGroups: CellProcessGroupsApi
        inputPorts: CellPortsApi
        outputPorts: CellPortsApi
        labels: CellItemApi
        funnels: CellItemApi
        connections: CellConnectionsApi
        templates: CellItemApi
        remoteProcessGroups: CellItemApi
    }

    export interface CellItemApi extends Record<string, any> {
        name: NIFI_CAMEL_NAME
        // 初始化  blank 没有
        init: (data: any | any[], mds?: any[]) => any

        
        // 刷新元素 调用接口并更新元素数据
        refresh: (cell: Cell) => void

        // 编辑元素
        edit: (cell: Cell) => Promise<VNode>
        view: (cell: Cell) => Promise<VNode>

        // 右键菜单
        contextmenu: (cell?: Cell) => VNode
        // 更新元素数据 和 状态
        update: (tds: any | any[]) => void

    }

    export interface CellConnectionsApi extends CellItemApi {
        add: (md: any, edge: Cell) => void
        updateStatus: (e: SC) => void
    }

    export interface CellProcessGroupsApi extends CellItemApi {
        edit: (cell?: Cell | boolean) => Promise<VNode>
        goto: (cell?:Cell) => void
        togglePower(cell:Cell):void
    }

    export interface CellPorcessorsApi extends CellItemApi {
        // 新增算子
        add(data: any): void
        // 启用
        enable(cell: Cell): void
        // 禁用
        disable(cell: Cell): void
        // 运行
        run(cell: Cell): void
        // 停止
        stop(cell: Cell): void
        // 运行一次
        runOnce(cell: Cell): void
        // 数据溯源
        provance(cell: Cell): void
        // 
        getMetadata: (type: string) => CellMeatadata
        togglePower(cell:Cell):void
    }

    export interface CellPortsApi extends CellItemApi {

    }

    export interface CellMeatadata {
        type: string | string[] // 元素类型名称
        // 自定义的表单
        form?: VNode | Component
        // 表单打开前回调 可通过返回值控制是否打开表单
        beforeOpen?: (cell: SC) => boolean
        // 表单打开之后的回调
        open?: (cell: SC) => void
        // 表单关闭之后的回调
        close?: (cell: SC) => void
        // 表单关闭之前的回调 可通过 返回值控制表单是否关闭
        beforeClose?: (model: any, elForm: any, cell: SC) => Promise<boolean>
        // 提交之后的回调
        submit?: (cell: SC) => void;
        // 表单提交之前的回调 可通过返回值控制是否提交表单 第一个参数是表单值，第二个参数是表单实例，第三个参数是当前 cell
        beforeSubmit?: (model: any, elForm: any, cell: SC) => Promise<boolean>
        // 元素初始化的时候的回调
        init?: (cell: SC) => void
        // 元素与其他元素建立连接的回调
        connected?: (node: SC, edge: SC) => void
        // 需要添加到常用属性的表单属性名集合
        includeProps?: string[]
        // 排除的表单属性集合
        excludeProps?: string[]
        // 边默认的选中关系
        defaultRelations?: string[]
        // // 元素的 metdata 配置
        // md?:Cell.Metadata 
        // 输入输出连接桩 ID 配置
        inputPort?: string
        outputPort?: string

    }

    export interface NodeMetadata {
        // 节点类型
        type: string
        // 节点 标签名
        label: string
        // 节点分组名
        group?: string
        // 节点排序 升序排序
        sort?: number
        // 节点图标
        icon?: string
        // 输入桩 Id
        inputPort?: string
        // 输出桩 ID
        outputPort?: string
        // 基础属性中包含的属性集合
        includeProps?: string
        // 需要排除的属性集合
        excludeProps?: string
    }

    export interface BaseModule {
        name:string
        // 初始化数据
        init:(data:any[]|any) => any[];
        // render done 回调
        done?:() => void;
        // 初始化 hook 回调钩子
        initHook?:() => void
        // 新增元素
        add:(data:any) => Promise<void>
        // 更新元素
        set:(data:any) => Promise<void>;
        // 删除元素
        del:(data:any) => Promise<void>
        // 刷新单个元素
        refresh:(cell:Cell) => void
        // 刷新数据
        update:(data:any) => void
        // 编辑元素
        edit:(cell:Cell,evt?:any) => void
        // 查看元素
        view:(cell:Cell) => void
        // 右键菜单
        contextmenu:(cell:Cell,evt:MouseEvent) => void
    }

    export interface ModuleProcessors extends BaseModule {
        togglePower:(cell:Cell) => void
        changeState:(cell:Cell,state:CellState) => void // 改变状态
        run:(cell:Cell) => void // 运行
        runOnce:(cell:Cell) => void // 运行一次
        stop:(cell:Cell) => void // 停止
        disable:(cell:Cell) => void // 禁用
        enable:(cell:Cell) => void // 启用
        //
        getMetadata:(type:string) => any // 获取一个算子类型的配置数据，包含外部的配置数据 
        provance:(cell:Cell) => void // 数据溯源
    }
    export interface ModuleConnections extends Omit<BaseModule,'init'|"add"> {
        updateStatus:(id:string) => void
        updateData:(id:string) => void
        add:(data:any,cell:Cell) => Promise<void>
        init:(data:any[]|any,mds:any[]) => any[];
    }
    export interface ModuleBlank extends Pick<BaseModule,"name"> { 
        contextmenu:() => VNode
    }
    export interface ModuleFunnels extends BaseModule { }
    export interface ModuleProcessGroup extends BaseModule {
        view:(cell?:Cell) => void
        edit:(cell?:Cell) => void
        // 全部启动
        start:(cell?:Cell) => void
        // 全部停止
        stop:(cell?:Cell) => void
        // 全部禁用
        disable:(cell?:Cell) => void
        // 全部启用
        enable:(cell?:Cell) => void
        // 清空队列
        clear:(cell?:Cell) => void
        // 

    }
    export interface ModuleLabels extends BaseModule {

    }
    export interface MoudleOutputPorts extends BaseModule { addNode:(d:any) => Promise<any> }
    export interface ModuleInputPorts extends BaseModule {
        addNode:(d:any) => Promise<any> 
     }
    export interface ModuleRemoteProcessGroup extends BaseModule { }

    export type CellState = "RUN_ONCE" | "STOPPED" | "RUNNING" | "DISABLED";

    export interface Cells {
        data: Map<string, any>
        set: (data: any) => void;
        get: (cell: SC) => any
        has:(cell:SC) => boolean
        del:(cell:SC) => void
        //
        addHook:(sid:string,tid:string,f:any) => void
        runHook:(id:string,d:any) => void
        delHook:(id:string) => void
        //
        getCellRevision: (cell: SC) => any
        getCellVersion: (cell: SC) => number
        //
        getCell: (cell: Cell,message?:string) => Promise<any>
        delCell: (cell: Cell,message?:string) => Promise<any>
        addCell: (name: string, data: any,message?:string) => Promise<any>
        setCell: (cell: Cell, data: any,message?:string) => Promise<any>
        //
        setCellState: (cell: Cell, state: CellState) => Promise<any>;
        //
        handleEdit: () => void
        handleView: () => void
        // modules
        processors: ModuleProcessors
        connections: ModuleConnections
        blank: ModuleBlank
        funnels: ModuleFunnels
        processGroups: ModuleProcessGroup
        labels: ModuleLabels
        outputPorts: MoudleOutputPorts
        inputPorts: ModuleInputPorts
        remoteProcessGroup: ModuleRemoteProcessGroup
    }



    export interface BoxEl {
        el?:HTMLElement
        close:() => void
    }

    export interface DialogEl extends BoxEl {
        submit:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        cancel:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        finish:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        handleSubmit:(e?:any) => void
        handleCancel:(e?:any) => void
    }

    export interface ProverEl extends BoxEl {
        open:() => void
    }

    export interface DrawerEl extends BoxEl {
        open:() => void
    }
}